package mock;


import com.github.javafaker.Faker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.sql.*;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.Date;
import java.util.stream.Collectors;

public class TourismDataGenerator {
    private static final String DB_URL = "jdbc:mysql://192.168.10.102:3306/smart_tour?useSSL=false&requireSSL=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&allowPublicKeyRetrieval=true";
    private static final String DB_USER = "root";
    private static final String DB_PASSWORD = "000000";
    private static final int BATCH_SIZE = 100;
    private static final Logger logger = LoggerFactory.getLogger(TourismDataGenerator.class);

    public static void main(String[] args) {
        int count = 5000; // 默认生成5000条数据
        LocalDateTime startTime = LocalDateTime.now().minusMonths(6); // 默认从6个月前开始
        LocalDateTime endTime = LocalDateTime.now(); // 到现在为止

        // 解析命令行参数
        if (args.length >= 1) {
            count = Integer.parseInt(args[0]);
        }
        if (args.length >= 4) {
            startTime = LocalDateTime.of(
                    Integer.parseInt(args[1]), // 年
                    Integer.parseInt(args[2]), // 月
                    Integer.parseInt(args[3]), // 日
                    0, 0); // 时分设为0
        }
        if (args.length >= 7) {
            endTime = LocalDateTime.of(
                    Integer.parseInt(args[4]), // 年
                    Integer.parseInt(args[5]), // 月
                    Integer.parseInt(args[6]), // 日
                    23, 59); // 时分设为23:59
        }

        generateData(count, startTime, endTime);
    }

    public static void generateData(int count, LocalDateTime startTime, LocalDateTime endTime) {
        Faker faker = new Faker(Locale.CHINA);
        Random random = new Random();

        // 存储生成的数据列表
        List<UserInfo> userInfoList = new ArrayList<>();
        List<TourProduct> tourProductList = new ArrayList<>();
        List<Supplier> supplierList = new ArrayList<>();
        List<OrderInfo> orderInfoList = new ArrayList<>();
        List<UserReview> userReviewList = new ArrayList<>();
        List<RecommendationLog> recommendationLogList = new ArrayList<>();
        List<TravelGuide> travelGuideList = new ArrayList<>();
        List<TravelActivity> travelActivityList = new ArrayList<>();
        List<UserFavorite> userFavoriteList = new ArrayList<>();

        // 生成供应商数据
        generateSupplierData(supplierList, count / 10, faker, startTime, endTime);
        System.out.println("成功生成 " + supplierList.size() + " 条供应商数据");

        // 生成用户数据
        generateUserInfoData(userInfoList, count, faker, startTime, endTime);
        System.out.println("成功生成 " + userInfoList.size() + " 条用户数据");

        // 生成旅游产品数据
        generateTourProductData(tourProductList, count / 3, faker, random, supplierList, startTime, endTime);
        System.out.println("成功生成 " + tourProductList.size() + " 条旅游产品数据");

        // 生成订单数据
        if (userInfoList == null || userInfoList.isEmpty() || tourProductList == null || tourProductList.isEmpty()) {
            System.out.println("用户或产品数据为空，跳过订单生成！");
            return;
        }
        generateOrderInfoData(orderInfoList, count, faker, random, userInfoList, tourProductList, startTime, endTime);
        System.out.println("成功生成 " + orderInfoList.size() + " 条订单数据");

        // 生成用户评价数据
        generateUserReviewData(userReviewList, orderInfoList, faker, random, startTime, endTime);
        System.out.println("成功生成 " + userReviewList.size() + " 条用户评价数据");

        // 生成推荐记录数据
        generateRecommendationLogData(recommendationLogList, count / 2, faker, random, userInfoList, tourProductList, startTime, endTime);
        System.out.println("成功生成 " + recommendationLogList.size() + " 条推荐记录数据");

        // 生成旅游攻略数据
        generateTravelGuideData(travelGuideList, count / 5, faker, random, userInfoList, startTime, endTime);
        System.out.println("成功生成 " + travelGuideList.size() + " 条旅游攻略数据");

        // 生成旅游活动数据
        generateTravelActivityData(travelActivityList, count / 10, faker, random, startTime, endTime);
        System.out.println("成功生成 " + travelActivityList.size() + " 条旅游活动数据");

        // 生成收藏数据
        generateUserFavoriteData(userFavoriteList, count / 2, faker, random, userInfoList, tourProductList, travelGuideList, startTime, endTime);
        System.out.println("成功生成 " + userFavoriteList.size() + " 条收藏数据");
    }

    // 生成供应商数据
    private static void generateSupplierData(List<Supplier> supplierList, int count, Faker faker, LocalDateTime startTime, LocalDateTime endTime) {
        System.out.println("开始生成supplier数据...");
        for (int i = 1; i <= count; i++) {
            LocalDateTime createTime = randomLocalDateTime(faker, startTime, endTime);
            Supplier supplier = Supplier.builder()
                    .supplierId(i)
                    .name(faker.company().name())
                    .contactName(faker.name().fullName())
                    .contactPhone(faker.phoneNumber().subscriberNumber(11))
                    .address(faker.address().fullAddress())
                    .rating(faker.number().randomDouble(1, 3, 5))
                    .createTime(createTime)
                    .build();
            supplierList.add(supplier);
        }
        System.out.println("生成supplier数据条数：" + supplierList.size());
        insertSupplierData(supplierList);
        System.out.println("插入supplier数据完成");
    }

    // 生成用户数据
    private static void generateUserInfoData(List<UserInfo> userInfoList, int count, Faker faker, LocalDateTime startTime, LocalDateTime endTime) {
        System.out.println("开始生成user_info数据...");
        String[] favoriteTags = {"徒步", "美食", "亲子", "摄影", "购物", "文化探索", "海滩度假", "山地探险"};
        String[] interests = {"旅游", "美食", "摄影", "阅读", "音乐", "电影", "运动", "科技", "历史", "艺术"};
        for (int i = 1; i <= count; i++) {
            LocalDateTime registerTime = randomLocalDateTime(faker, startTime, endTime);
            LocalDateTime lastLoginTime = registerTime.plusDays(faker.number().numberBetween(1, 180));
            int ageGroup = faker.number().numberBetween(1, 7);
            int gender = faker.number().numberBetween(0, 3);
            String tags = Arrays.stream(favoriteTags)
                    .filter(t -> faker.random().nextBoolean())
                    .limit(3)
                    .collect(Collectors.joining(","));
            String interestStr = Arrays.stream(interests)
                    .filter(it -> faker.random().nextBoolean())
                    .limit(3)
                    .collect(Collectors.joining(","));
            UserInfo user = UserInfo.builder()
                    .userId(i)
                    .username(faker.name().fullName())
                    .mobile(faker.phoneNumber().subscriberNumber(11))
                    .ageGroup(ageGroup)
                    .gender(gender)
                    .userLevel(1)
                    .registerTime(registerTime)
                    .lastLoginTime(lastLoginTime)
                    .favoriteTags(tags)
                    .interests(interestStr)
                    .build();
            userInfoList.add(user);
        }
        System.out.println("生成user_info数据条数：" + userInfoList.size());
        insertUserInfoData(userInfoList);
        System.out.println("插入user_info数据完成");
    }

    // 生成旅游产品数据
    private static void generateTourProductData(List<TourProduct> tourProductList, int count, Faker faker, Random random,
                                                List<Supplier> supplierList, LocalDateTime startTime, LocalDateTime endTime) {
        System.out.println("开始生成tour_product数据...");
        if (supplierList == null || supplierList.isEmpty()) {
            System.out.println("供应商数据为空，跳过旅游产品生成！");
            return;
        }
        String[] productTypes = {"酒店", "景点门票", "旅游线路", "交通票", "餐饮套餐"};
        int[] productTypeValues = {1, 2, 3, 4, 5};
        for (int i = 1; i <= count; i++) {
            int typeIndex = random.nextInt(productTypes.length);
            int productType = productTypeValues[typeIndex];
            String typeName = productTypes[typeIndex];
            Supplier supplier = supplierList.get(random.nextInt(supplierList.size()));
            String city = faker.address().cityName();
            String name = faker.company().name() + " - " + city + "特色产品";
            String description = faker.company().catchPhrase() + "。" + faker.address().fullAddress() + "。";
            String highlightFeatures = faker.company().catchPhrase();
            TourProduct product = TourProduct.builder()
                    .productId(i)
                    .productType(productType)
                    .name(name)
                    .description(description)
                    .price(BigDecimal.valueOf(faker.number().randomDouble(2, 50, 2000)))
                    .inventory(faker.number().numberBetween(10, 1000))
                    .city(city)
                    .starLevel(faker.number().numberBetween(1, 6))
                    .supplierId(supplier != null ? supplier.getSupplierId() : 1)
                    .highlightFeatures(highlightFeatures)
                    .build();
            tourProductList.add(product);
        }
        System.out.println("生成tour_product数据条数：" + tourProductList.size());
        insertTourProductData(tourProductList);
        System.out.println("插入tour_product数据完成");
    }

    // 生成订单数据
    private static void generateOrderInfoData(List<OrderInfo> orderInfoList, int count, Faker faker, Random random,
                                              List<UserInfo> userInfoList, List<TourProduct> tourProductList,
                                              LocalDateTime startTime, LocalDateTime endTime) {
        System.out.println("开始生成order_info数据...");
        if (userInfoList == null || userInfoList.isEmpty() || tourProductList == null || tourProductList.isEmpty()) {
            System.out.println("用户或产品数据为空，跳过订单生成！");
            return;
        }
        for (int i = 1; i <= count; i++) {
            LocalDateTime orderTime = randomLocalDateTime(faker, startTime, endTime);
            LocalDateTime useTime = orderTime.plusDays(faker.number().numberBetween(1, 90));
            UserInfo user = userInfoList.get(random.nextInt(userInfoList.size()));
            TourProduct product = tourProductList.get(random.nextInt(tourProductList.size()));
            int status = getRandomOrderStatus(random);
            int paymentMethod = random.nextInt(3) + 1;
            int people = random.nextInt(5) + 1;
            BigDecimal totalAmount = (product != null && product.getPrice() != null) ? product.getPrice().multiply(BigDecimal.valueOf(people)) : BigDecimal.ZERO;
            OrderInfo order = OrderInfo.builder()
                    .orderId(UUID.randomUUID().toString())
                    .userId(user != null ? user.getUserId() : 1)
                    .productId(product != null ? product.getProductId() : 1)
                    .orderTime(orderTime)
                    .status(status)
                    .paymentMethod(paymentMethod)
                    .totalAmount(totalAmount)
                    .useTime(useTime)
                    .build();
            orderInfoList.add(order);
        }
        System.out.println("生成order_info数据条数：" + orderInfoList.size());
        insertOrderInfoData(orderInfoList);
        System.out.println("插入order_info数据完成");
    }

    // 生成用户评价数据
    private static void generateUserReviewData(List<UserReview> userReviewList, List<OrderInfo> orderInfoList,
                                               Faker faker, Random random, LocalDateTime startTime, LocalDateTime endTime) {
        System.out.println("开始生成user_review数据...");
        int reviewId = 1;
        for (OrderInfo order : orderInfoList) {
            if (order.getStatus() == 3) {
                LocalDateTime reviewTime = order.getUseTime() != null ? order.getUseTime().plusDays(faker.number().numberBetween(1, 30)) : LocalDateTime.now();
                String content = faker.company().catchPhrase() + "，非常满意！";
                UserReview review = UserReview.builder()
                        .reviewId(reviewId++)
                        .userId(order.getUserId())
                        .productId(order.getProductId())
                        .reviewTime(reviewTime)
                        .score(faker.number().numberBetween(1, 6))
                        .content(content)
                        .helpfulVotes(faker.number().numberBetween(0, 101))
                        .build();
                userReviewList.add(review);
            }
        }
        System.out.println("生成user_review数据条数：" + userReviewList.size());
        insertUserReviewData(userReviewList);
        System.out.println("插入user_review数据完成");
    }

    // 生成推荐记录数据
    private static void generateRecommendationLogData(List<RecommendationLog> recommendationLogList, int count,
                                                      Faker faker, Random random, List<UserInfo> userInfoList,
                                                      List<TourProduct> tourProductList, LocalDateTime startTime, LocalDateTime endTime) {
        System.out.println("开始生成recommendation_log数据...");
        for (int i = 1; i <= count; i++) {
            LocalDateTime recommendTime = randomLocalDateTime(faker, startTime, endTime);
            UserInfo user = userInfoList.isEmpty() ? null : userInfoList.get(random.nextInt(userInfoList.size()));
            TourProduct product = tourProductList.isEmpty() ? null : tourProductList.get(random.nextInt(tourProductList.size()));
            int exposureCount = faker.number().numberBetween(1, 101);
            int clickCount = faker.number().numberBetween(0, exposureCount + 1);
            double conversionRate = exposureCount > 0 ? (double) clickCount / exposureCount : 0.0;
            RecommendationLog log = RecommendationLog.builder()
                    .logId(i)
                    .userId(user != null ? user.getUserId() : 1)
                    .recommendedId(product != null ? product.getProductId() : 1)
                    .recommendTime(recommendTime)
                    .exposureCount(exposureCount)
                    .clickCount(clickCount)
                    .conversionRate(conversionRate)
                    .build();
            recommendationLogList.add(log);
        }
        System.out.println("生成recommendation_log数据条数：" + recommendationLogList.size());
        insertRecommendationLogData(recommendationLogList);
        System.out.println("插入recommendation_log数据完成");
    }

    // 生成旅游攻略数据
    private static void generateTravelGuideData(List<TravelGuide> travelGuideList, int count, Faker faker, Random random,
                                                List<UserInfo> userInfoList, LocalDateTime startTime, LocalDateTime endTime) {
        System.out.println("开始生成travel_guide数据...");
        for (int i = 1; i <= count; i++) {
            LocalDateTime publishTime = randomLocalDateTime(faker, startTime, endTime);
            String destination = faker.address().cityName();
            String title = "畅游" + destination + " - " + faker.company().catchPhrase();
            String content = "攻略内容：" + faker.company().catchPhrase() + "。" + faker.address().fullAddress() + "。";
            UserInfo author = userInfoList.isEmpty() ? null : userInfoList.get(random.nextInt(userInfoList.size()));
            TravelGuide guide = TravelGuide.builder()
                    .guideId(i)
                    .title(title)
                    .destination(destination)
                    .content(content)
                    .author(author != null ? author.getUserId() : 1)
                    .publishTime(publishTime)
                    .viewCount(faker.number().numberBetween(0, 10001))
                    .build();
            travelGuideList.add(guide);
        }
        System.out.println("生成travel_guide数据条数：" + travelGuideList.size());
        insertTravelGuideData(travelGuideList);
        System.out.println("插入travel_guide数据完成");
    }

    // 生成旅游活动数据
    private static void generateTravelActivityData(List<TravelActivity> travelActivityList, int count, Faker faker, Random random,
                                                   LocalDateTime startTime, LocalDateTime endTime) {
        System.out.println("开始生成travel_activity数据...");
        int actualCount = Math.max(1, count);
        System.out.println("将要生成的travel_activity数量：" + actualCount);
        for (int i = 1; i <= actualCount; i++) {
            LocalDateTime activityStartTime = randomLocalDateTime(faker, startTime, endTime.plusMonths(3));
            LocalDateTime activityEndTime = activityStartTime.plusDays(faker.number().numberBetween(1, 11));
            String name = "【" + faker.company().name() + "】" + faker.address().cityName() + "主题活动";
            String description = "本次活动由" + faker.company().name() + "主办，地点：" + faker.address().fullAddress() +
                    "。活动介绍：" + faker.company().catchPhrase() + "，欢迎" + faker.name().fullName() + "等嘉宾参与。";
            TravelActivity activity = TravelActivity.builder()
                    .name(name)
                    .startTime(activityStartTime)
                    .endTime(activityEndTime)
                    .location(faker.address().cityName() + " " + faker.address().streetName())
                    .description(description)
                    .price(BigDecimal.valueOf(faker.number().randomDouble(2, 0, 2000)))
                    .capacity(faker.number().numberBetween(20, 201))
                    .remainingSeats(faker.number().numberBetween(10, 201))
                    .build();
            travelActivityList.add(activity);
        }
        System.out.println("生成travel_activity数据条数：" + travelActivityList.size());
        insertTravelActivityData(travelActivityList);
        System.out.println("插入travel_activity数据完成");
    }

    // 生成收藏数据
    private static void generateUserFavoriteData(List<UserFavorite> userFavoriteList, int count, Faker faker, Random random,
                                                 List<UserInfo> userInfoList, List<TourProduct> tourProductList,
                                                 List<TravelGuide> travelGuideList, LocalDateTime startTime, LocalDateTime endTime) {
        System.out.println("开始生成user_favorite数据...");
        for (int i = 1; i <= count; i++) {
            LocalDateTime createTime = randomLocalDateTime(faker, startTime, endTime);
            UserInfo user = userInfoList.isEmpty() ? null : userInfoList.get(random.nextInt(userInfoList.size()));
            if (random.nextBoolean() && !tourProductList.isEmpty()) {
                TourProduct product = tourProductList.get(random.nextInt(tourProductList.size()));
                userFavoriteList.add(UserFavorite.builder()
                        .favoriteId(i)
                        .userId(user != null ? user.getUserId() : 1)
                        .itemId(product.getProductId())
                        .itemType(1)
                        .createTime(createTime)
                        .build());
            } else if (!travelGuideList.isEmpty()) {
                TravelGuide guide = travelGuideList.get(random.nextInt(travelGuideList.size()));
                userFavoriteList.add(UserFavorite.builder()
                        .favoriteId(i)
                        .userId(user != null ? user.getUserId() : 1)
                        .itemId(guide.getGuideId())
                        .itemType(2)
                        .createTime(createTime)
                        .build());
            }
        }
        System.out.println("生成user_favorite数据条数：" + userFavoriteList.size());
        insertUserFavoriteData(userFavoriteList);
        System.out.println("插入user_favorite数据完成");
    }

    // 随机订单状态生成(带权重)
    private static int getRandomOrderStatus(Random random) {
        // 0:待支付, 1:已支付, 2:已取消, 3:已完成
        int[] statuses = {0, 1, 2, 3};
        // 调整概率，让已完成订单更多
        int[] weights = {1, 3, 1, 5};
        int sum = Arrays.stream(weights).sum();
        int randomNum = random.nextInt(sum);

        int cumulative = 0;
        for (int i = 0; i < statuses.length; i++) {
            cumulative += weights[i];
            if (randomNum < cumulative) {
                return statuses[i];
            }
        }
        return statuses[3];
    }

    // 生成随机时间
    private static LocalDateTime randomLocalDateTime(Faker faker, LocalDateTime start, LocalDateTime end) {
        long startEpoch = start.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
        long endEpoch = end.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
        long randomEpoch = faker.date().between(new Date(startEpoch), new Date(endEpoch)).getTime();
        return LocalDateTime.ofInstant(Instant.ofEpochMilli(randomEpoch), ZoneId.systemDefault());
    }

    // 批量插入数据的通用方法
    @FunctionalInterface
    private interface BatchSetter<T> {
        void setValues(PreparedStatement pstmt, T item) throws SQLException;
    }

    private static <T> void executeBatchInsert(String sql, List<T> items, BatchSetter<T> setter) {
        if (items == null || items.isEmpty()) return;
        try (Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD)) {
            conn.setAutoCommit(false);
            try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
                for (T item : items) {
                    setter.setValues(pstmt, item);
                    pstmt.addBatch();
                }
                pstmt.executeBatch();
                conn.commit();
            } catch (SQLException e) {
                conn.rollback();
                logger.error("SQL执行批量插入时发生异常，已回滚", e);
            }
        } catch (SQLException e) {
            logger.error("数据库连接或批量插入发生异常", e);
        }
    }

    // 各表的插入方法
    private static void insertSupplierData(List<Supplier> supplierList) {
        String sql = "INSERT INTO supplier (name, contact_name, contact_phone, address, rating, create_time) VALUES (?, ?, ?, ?, ?, ?)";
        executeBatchInsert(sql, supplierList, (pstmt, supplier) -> {
            pstmt.setString(1, supplier.getName());
            pstmt.setString(2, supplier.getContactName());
            pstmt.setString(3, supplier.getContactPhone());
            pstmt.setString(4, supplier.getAddress());
            pstmt.setDouble(5, supplier.getRating());
            pstmt.setTimestamp(6, Timestamp.valueOf(supplier.getCreateTime()));
        });
    }

    private static void insertUserInfoData(List<UserInfo> userInfoList) {
        String sql = "INSERT INTO user_info (username, mobile, age_group, gender, user_level, register_time, last_login_time, favorite_tags, interests) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
        executeBatchInsert(sql, userInfoList, (pstmt, user) -> {
            pstmt.setString(1, user.getUsername());
            pstmt.setString(2, user.getMobile());
            pstmt.setInt(3, user.getAgeGroup());
            pstmt.setInt(4, user.getGender());
            pstmt.setInt(5, user.getUserLevel());
            pstmt.setTimestamp(6, user.getRegisterTime() != null ? Timestamp.valueOf(user.getRegisterTime()) : null);
            pstmt.setTimestamp(7, user.getLastLoginTime() != null ? Timestamp.valueOf(user.getLastLoginTime()) : null);
            pstmt.setString(8, user.getFavoriteTags() != null ? user.getFavoriteTags() : "");
            pstmt.setString(9, user.getInterests() != null ? user.getInterests() : "");
        });
    }

    private static void insertTourProductData(List<TourProduct> tourProductList) {
        String sql = "INSERT INTO tour_product (product_id, product_type, name, description, price, inventory, city, star_level, supplier_id, highlight_features) " +
                "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
        executeBatchInsert(sql, tourProductList, (pstmt, product) -> {
            pstmt.setInt(1, product.getProductId());
            pstmt.setInt(2, product.getProductType());
            pstmt.setString(3, product.getName());
            pstmt.setString(4, product.getDescription());
            pstmt.setDouble(5, product.getPrice() != null ? product.getPrice().doubleValue() : 0);
            pstmt.setInt(6, product.getInventory());
            pstmt.setString(7, product.getCity());
            pstmt.setInt(8, product.getStarLevel());
            pstmt.setInt(9, product.getSupplierId());
            pstmt.setString(10, product.getHighlightFeatures());
        });
    }

    private static void insertOrderInfoData(List<OrderInfo> orderInfoList) {
        String sql = "INSERT INTO order_info (order_id, user_id, product_id, order_time, status, payment_method, total_amount, use_time) " +
                "VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
        executeBatchInsert(sql, orderInfoList, (pstmt, order) -> {
            pstmt.setString(1, order.getOrderId());
            pstmt.setInt(2, order.getUserId());
            pstmt.setInt(3, order.getProductId());
            pstmt.setTimestamp(4, order.getOrderTime() != null ? Timestamp.valueOf(order.getOrderTime()) : null);
            pstmt.setInt(5, order.getStatus());
            pstmt.setInt(6, order.getPaymentMethod());
            pstmt.setDouble(7, order.getTotalAmount() != null ? (order.getTotalAmount() instanceof BigDecimal ? ((BigDecimal) order.getTotalAmount()).doubleValue() : Double.parseDouble(order.getTotalAmount().toString())) : 0);
            pstmt.setTimestamp(8, order.getUseTime() != null ? Timestamp.valueOf(order.getUseTime()) : null);
        });
    }

    private static void insertUserReviewData(List<UserReview> userReviewList) {
        String sql = "INSERT INTO user_review (review_id, user_id, product_id, review_time, score, content, helpful_votes) " +
                "VALUES (?, ?, ?, ?, ?, ?, ?)";
        executeBatchInsert(sql, userReviewList, (pstmt, review) -> {
            pstmt.setInt(1, review.getReviewId());
            pstmt.setInt(2, review.getUserId());
            pstmt.setInt(3, review.getProductId());
            pstmt.setTimestamp(4, Timestamp.valueOf(review.getReviewTime()));
            pstmt.setInt(5, review.getScore());
            pstmt.setString(6, review.getContent());
            pstmt.setInt(7, review.getHelpfulVotes());
        });
    }

    private static void insertRecommendationLogData(List<RecommendationLog> recommendationLogList) {
        String sql = "INSERT INTO recommendation_log (log_id, user_id, recommended_id, recommend_time, exposure_count, click_count, conversion_rate) " +
                "VALUES (?, ?, ?, ?, ?, ?, ?)";
        executeBatchInsert(sql, recommendationLogList, (pstmt, log) -> {
            pstmt.setInt(1, log.getLogId());
            pstmt.setInt(2, log.getUserId());
            pstmt.setInt(3, log.getRecommendedId());
            pstmt.setTimestamp(4, Timestamp.valueOf(log.getRecommendTime()));
            pstmt.setInt(5, log.getExposureCount());
            pstmt.setInt(6, log.getClickCount());
            pstmt.setDouble(7, log.getConversionRate());
        });
    }

    private static void insertTravelGuideData(List<TravelGuide> travelGuideList) {
        String sql = "INSERT INTO travel_guide (guide_id, title, destination, content, author, publish_time, view_count) " +
                "VALUES (?, ?, ?, ?, ?, ?, ?)";
        executeBatchInsert(sql, travelGuideList, (pstmt, guide) -> {
            pstmt.setInt(1, guide.getGuideId());
            pstmt.setString(2, guide.getTitle());
            pstmt.setString(3, guide.getDestination());
            pstmt.setString(4, guide.getContent());
            pstmt.setInt(5, guide.getAuthor() != null ? guide.getAuthor() : 0);
            pstmt.setTimestamp(6, Timestamp.valueOf(guide.getPublishTime()));
            pstmt.setInt(7, guide.getViewCount());
        });
    }

    private static void insertTravelActivityData(List<TravelActivity> travelActivityList) {
        String sql = "INSERT INTO travel_activity (name, start_time, end_time, location, description, price, capacity, remaining_seats) " +
                "VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
        executeBatchInsert(sql, travelActivityList, (pstmt, activity) -> {
            pstmt.setString(1, activity.getName());
            pstmt.setTimestamp(2, activity.getStartTime() != null ? Timestamp.valueOf(activity.getStartTime()) : null);
            pstmt.setTimestamp(3, activity.getEndTime() != null ? Timestamp.valueOf(activity.getEndTime()) : null);
            pstmt.setString(4, activity.getLocation());
            pstmt.setString(5, activity.getDescription());
            pstmt.setDouble(6, activity.getPrice() != null ? activity.getPrice().doubleValue() : 0);
            pstmt.setInt(7, activity.getCapacity());
            pstmt.setInt(8, activity.getRemainingSeats());
        });
    }

    private static void insertUserFavoriteData(List<UserFavorite> userFavoriteList) {
        String sql = "INSERT INTO user_favorite (favorite_id, user_id, item_id, item_type, create_time) " +
                "VALUES (?, ?, ?, ?, ?)";
        executeBatchInsert(sql, userFavoriteList, (pstmt, favorite) -> {
            pstmt.setInt(1, favorite.getFavoriteId());
            pstmt.setInt(2, favorite.getUserId());
            pstmt.setInt(3, favorite.getItemId());
            pstmt.setInt(4, favorite.getItemType());
            pstmt.setTimestamp(5, Timestamp.valueOf(favorite.getCreateTime()));
        });
    }
}